package index.btree;

import compiler.absyn.Constant;

import storage.file.Block;
import storage.record.RID;
import storage.record.TableInfo;
import storage.tx.Transaction;

public class BTreeLeaf {
	private TableInfo md;
	private Transaction tx;
	private String filename;
	private Constant searchkey;
	private BTreePage contents;
	private int currentslot;
	
	public BTreeLeaf(Block blk, TableInfo md, Constant searchkey, Transaction tx){
		this.md = md;
		this.searchkey = searchkey;
		this.tx = tx;
		filename = blk.getFileName();
		contents = new BTreePage(blk, md, tx);
		currentslot = contents.findSlotBefore(searchkey);
	}
	
	public void close(){
		contents.close();
	}
	
	public boolean next(){
		currentslot++;
		while(currentslot >= contents.getNumRecs())
			if(!moveToOverFlow())
				return false;
		return contents.getDataVal(currentslot).equals(searchkey);
	}
	
	public RID getDataRid(){
		return contents.getDataRid(currentslot);
	}
	
	public void delete(RID rid){
		while(next()){
			if(getDataRid().equals(rid)){
				contents.delete(currentslot);
				return;
			}
		}
	}
	
	public DirEntry insert(RID rid){
		currentslot++;
		contents.insertLeaf(currentslot, searchkey, rid);
		if (!contents.isFull()){
			return null;
		}
		Block newblk = contents.appendNew(filename, -1);
		BTreePage newpage = new BTreePage(newblk, md, tx);
		Constant splitval = contents.split(newpage);
		if(contents.getDataVal(0).equals(splitval)){
			newpage.setFlag(contents.getFlag());
			contents.setFlag(newblk.getBlkNum());
		}
		newpage.close();
		return new DirEntry(splitval, newblk.getBlkNum());
	}
	
	private boolean moveToOverFlow(){
		int blknum = contents.getFlag();
		if(blknum<0)
			return false;
		contents.close();
		Block nextblk = new Block(filename, blknum);
		contents = new BTreePage(nextblk, md, tx);
		currentslot = 0;
		return true;
	}

}
